home *** CD-ROM | disk | FTP | other *** search
Text File | 2004-09-30 | 39.5 KB | 1,495 lines |
- <![CDATA[
-
- // simple context object that caches project-specific settings defined in settings.dtd
- function CContext(oDoc, sDevLang, sMedia, sExt, sProj, sProjMask, sDefPlat, iAllowSelfUnregistered, iLuCache, iUseTargetsV2) //at //markda
- {
- this._oDoc = oDoc; // cache a reference to the current XML document
- this._devlang = sDevLang;
- this._media = sMedia;
- this._ext = sExt;
- this._proj = sProj
- this._projMask = sProjMask;
- this._defPlat = sDefPlat;
- this._bAllowSelfUnregistered = (iAllowSelfUnregistered ? true : false);
- this._paths = new Array();
-
- //markda: Switch that determines if targets v1 or v2 is used
- this._bUseTargetsV2 = (iUseTargetsV2 ? true : false);
-
- //at: Switch that determines if lookup caching is done (ie, LuCache).
- this._bCacheLookups = (iLuCache ? true : false);
-
- //at: Following code creates the target node "mini-dom" and
- //at: gets local hard drive for later targets.xml path assembly.
- this._oTDom = new ActiveXObject("Microsoft.XMLDOM");
- var re = /\/\/.:/i;
- var n = oDoc.url.search(re);
- if (n > 0)
- {
- var sVal = oDoc.url.substr(n+2, 2);
- this._sDrive = sVal.toLowerCase();
- }
- else
- this._sDrive = "";
- }
-
- CContext.prototype.GetPathOf = function(sKey)
- {
- return this._paths[sKey];
- }
-
- CContext.prototype.SetPathOf = function(sKey, sPath)
- {
- this._paths[sKey] = sPath;
- }
-
- // return a reference to the current document
- CContext.prototype.GetDocument = function()
- {
- return this._oDoc;
- }
-
- CContext.prototype.GetDevLang = function()
- {
- return this._devlang;
- }
-
- CContext.prototype.GetDefaultPlatform = function()
- {
- return this._defPlat;
- }
-
- CContext.prototype.AllowSelfUnregistered = function()
- {
- return this._bAllowSelfUnregistered;
- }
-
- //at: Return true if Lookup Caching is on.
- CContext.prototype.CacheLookups = function()
- {
- return this._bCacheLookups;
- }
-
- //at: Force Turn off of lookup caching.
- CContext.prototype.NoCacheLookups = function()
- {
- this._bCacheLookups = false;
- }
-
- //markda: Return true if targets v2 required
- CContext.prototype.UseTargetsV2 = function()
- {
- return this._bUseTargetsV2;
- }
-
- // if an iface is marked as primary, return it
- // if more than one iface is marked as primary, return the first
- // if no ifaces are marked as primary, return the first
- function GetActiveIFace()
- {
- var oActiveIFaces = ownerDocument.selectNodes("/inetsdk:topic/metadata/applies/iface[@primary]");
- if (oActiveIFaces.length == 0)
- {
- var oActiveIFace = ownerDocument.selectSingleNode("/inetsdk:topic/metadata/applies/iface[0]");
- return oActiveIFace;
- }
- else
- {
- return oActiveIFaces[0];
- }
- }
-
- // does the current topic contain at least one remark specific to the specified platform
- function ContainsQualifyingRemarkForPlatform(oContainer, sDesiredPlat, sCurDLang)
- {
- var sDLangClause = "";
- if (sCurDLang != '')
- {
- sDLangClause = " $and$ not(@devlang) $or$ @devlang='" + sCurDLang + "'";
- }
-
- // ASSumes the current context is the parent of remarks
- var oPotentialRems = oContainer.selectNodes("remarks/rem[@platforms" + sDLangClause + "]");
- if (!oPotentialRems)
- {
- return false;
- }
-
- var oRegDesiredPlat = new RegExp("\\b" + sDesiredPlat + "\\b");
- for (var i = 0; i < oPotentialRems.length; i++)
- {
- // check to see if there's a rem specific to the specified platform
- if (IsQualifyingRemarkForPlatform(oPotentialRems[i], sDesiredPlat, oRegDesiredPlat, true) && IsQualifyingRemarkForActiveIFace(oPotentialRems[i], sCurDLang))
- {
- return true;
- }
- }
-
- return false;
- }
-
- // Return true if the specified remark applies to the desired platform
- // oRegDesiredPlat can be passed in as an optimization
- // When set to true, bFailIfNone indicates that the rem shouldn't qualify if no platforms are specified
- function IsQualifyingRemarkForPlatform(oRem, sDesiredPlat, oRegDesiredPlat, bFailIfNone)
- {
- var sPlatforms = oRem.getAttribute("platforms");
-
- if (!bFailIfNone)
- {
- bFailIfNone = false;
- }
-
- // no platforms were specified
- if (!sPlatforms)
- {
- return (bFailIfNone ? false : true);
- }
-
- if (!oRegDesiredPlat)
- {
- oRegDesiredPlat = new RegExp("\\b" + sDesiredPlat + "\\b");
- }
-
- if (oRegDesiredPlat.test(sPlatforms))
- {
- return true;
- }
-
- return false;
- }
-
- // does the topic contain any remarks that qualify
- // in the script case is there a remark that's either lang-neutral or script specific
- // in the cpp case is there a remark that's either lang-neutral or cpp specific. If it's cpp specific, does it pertain to the active iface
- // in the vb case?
- function ContainsQualifyingRemarkForDefaultPlatform(oCtx)
- {
- var oDoc = oCtx.GetDocument();
- if (!oDoc)
- {
- return false;
- }
-
- var sBaseQ = "/inetsdk:topic/content/remarks";
- var sCurLang = oCtx.GetDevLang();
- var sDefPlat = oCtx.GetDefaultPlatform();
-
- // is there a rem or a note that's devlang neutral?
- var oRems = oDoc.selectNodes(sBaseQ + "/rem[not(@devlang)] | " + sBaseQ + "/note[not(@devlang)]");
- if ((0 == oRems.length) && (!sCurLang || (/^\s*$/.test(sCurLang))))
- {
- // this is a language neutral topic that doesn't contain any neutral remarks. bail!
- return false;
- }
-
- // do one of the devlang neutral remarks qualify for the default platform?
- for (var iRem = 0; iRem < oRems.length; iRem++)
- {
- var oRem = oRems(iRem);
- // 110440: be sure to check for iface filter (@rids) since a remark can apply to any language but be restricted to
- // a particular iface in the cpp case
- if (IsQualifyingRemarkForPlatform(oRem, sDefPlat) && IsQualifyingRemarkForActiveIFace(oRem, sCurLang))
- {
- return true;
- }
- }
-
- // now deal with devlang-specific remarks
- oRems = oDoc.selectNodes(sBaseQ + "/rem[@devlang='" + sCurLang + "'] | " + sBaseQ + "/note[@devlang='" + sCurLang + "']");
- if (oRems.length == 0)
- {
- return false;
- }
-
- // drill in to see if the rem applies to the active iface
- for (iRem = 0; iRem < oRems.length; iRem++)
- {
- var oRem = oRems(iRem);
- if (IsQualifyingRemarkForPlatform(oRem, sDefPlat) && IsQualifyingRemarkForActiveIFace(oRem, sCurLang))
- {
- return true;
- }
- }
-
- return false;
- }
-
- // should the remark be included or filtered out
- function IsQualifyingRemarkForActiveIFace(oRem, sCurLang)
- {
- var sRIDs = oRem.getAttribute("rids");
- if (!sRIDs)
- {
- return true;
- }
-
- if ('cpp' != sCurLang)
- {
- return true;
- }
-
- var oActiveIFace = GetActiveIFace();
- if (!oActiveIFace)
- {
- return true;
- }
-
- var sActiveRID = oActiveIFace.getAttribute("rid");
- if (!sActiveRID)
- {
- // Yikes! DTD should NEVER allow this to occur
- return true;
- }
-
- var oRegInList = new RegExp("\\b" + sActiveRID + "\\b");
-
- if (oRegInList.test(sRIDs))
- {
- return true;
- }
-
- return false;
-
- }
-
- // added by chains 09/29/2000 (petertay)
- // does the topic contain any params that qualify for active iface
- function ContainsQualifyingParamForActiveIface(oCtx)
- {
-
- var oDoc = oCtx.GetDocument();
- if (!oDoc)
- {
- return false;
- }
-
- var sBaseQ = "/inetsdk:topic/content/params";
- var sCurLang = oCtx.GetDevLang();
-
- // is there a param that's devlang neutral?
- var oParamColl = oDoc.selectNodes(sBaseQ + "/param");
-
- // do one of the devlang neutral remarks qualify for the active iface?
- for (var iParam = 0; iParam < oParamColl.length; iParam++)
- {
- var oParam = oParamColl(iParam);
-
- // Filter out params w/autodesc and no script desc
- // autodesc not currently supported in script
- if (oParam.getAttribute("autodesc") && sCurLang == "scr")
- {
- var oScrDesc = oParam.selectNodes("desc[@devlang='scr']");
- if (oScrDesc.length == 0) continue;
- }
- if (QualifiesForActiveIFace(oParam, sCurLang))
- {
- return true;
- }
- }
-
- // now deal with devlang-specific remarks
- oParamColl = oDoc.selectNodes(sBaseQ + "/param[@devlang='" + sCurLang + "']");
- if (oParamColl.length == 0)
- {
- return false;
- }
-
- // drill in to see if the param applies to the active iface
- for (iParam = 0; iParam < oParamColl.length; iParam++)
- {
- var oParam = oParamColl(iParam);
- if (QualifiesForActiveIFace(oParam, sCurLang))
- {
- return true;
- }
- }
-
- return false;
- }
-
- // added by chains 09/29/2000 (petertay)
- // should the param be included or filtered out
- function QualifiesForActiveIFace(oElem, sCurLang)
- {
- var sRIDs = oElem.getAttribute("rids");
- if (!sRIDs)
- {
- return true;
- }
-
- if (sCurLang != 'cpp')
- {
- return true;
- }
-
- var oActiveIFace = GetActiveIFace();
- if (!oActiveIFace)
- {
- return true;
- }
-
- var sActiveRID = oActiveIFace.getAttribute("rid");
- if (!sActiveRID)
- {
- // Yikes! DTD should NEVER allow this to occur
- return true;
- }
-
- var oRegInList = new RegExp("\\b" + sActiveRID + "\\b");
-
- if (oRegInList.test(sRIDs))
- {
- return true;
- }
-
- return false;
-
- }
-
-
- // If the type start with a vowel or an H, the data type is soft
- // sounds and should be preceded by "an" rather than "a".
- function IsSoftSounding(sType)
- {
- if (!sType)
- {
- return false;
- }
- var oReg = /^[AaEeIiOoUuH]/;
- return (oReg.test(sType) ? true : false);
- }
-
- // This is only a poor guess that the param represented by o describes an interface
- function IsIFace(o)
- {
- var sType = o.getAttribute('type');
- if (!sType)
- {
- return false;
- }
-
- if (sType.substring(0,1) == "I" && o.getAttribute('pointerlevel') >= 1)
- {
- return true;
- }
- else
- {
- return false;
- }
- }
-
- // Return a portion of the path using the specified mask
- // iPortion values:
- // 0 == text before the mask,
- // 1 == text following the mask,
- // 2 == text before and including the mask,
- // 3 == text after and including the mask
- // if the mask cannot be found within the path, the entire path is returned
- function PartialPathOf(sPath, sMask, iPortion)
- {
- if (typeof(iPortion) == 'undefined')
- {
- return sPath;
- }
- //normalize the path. The document path when loaded from IE uses "/". But when loaded from script it uses "\".
- while (sPath.indexOf("\\")!=-1)
- {
- sPath=sPath.replace("\\","/");
- }
-
- var oReg = new RegExp("(.*)" + sMask + "(.*)", "i");
- if (oReg.test(sPath))
- {
- switch(iPortion)
- {
- case 0:
- return RegExp.$1;
- case 1:
- return RegExp.$2;
- case 2:
- return RegExp.$1 + sMask;
- case 3:
- return sMask + RegExp.$2;
- }
- }
- else
- {
- return sPath;
- }
- }
-
- // replicate the specified string (sRepl) iTimes times.
- function ReplStr(sRepl, iTimes)
- {
- var sOut = "";
- for (var i = 0; i < iTimes; i++)
- {
- sOut+=sRepl;
- }
- return sOut;
- }
-
- // Given an associative array, convert it to a string where each item is separated by the specified delimeter
- function StringFromHash(aHash, sDelim)
- {
- var s = "";
- for (sItem in aHash)
- {
- s += sItem + sDelim;
- }
-
- var oReg = new RegExp(sDelim + "$");
- s = s.replace(oReg, ""); // lop off trailing comma
- return s;
- }
-
- // Collect the conceptual index entries from the doc.
- // Indexer expects to find these as an IDX_CONCEPT expando on the top-level H1.
- // Web Crawlers expect to find these in the Keywords META.
- // HTMLHelp expects to find these in MS-HKWD METAs.
- function GatherConcepts(o, sDelim)
- {
- var aConcepts = {};
- var oDoc = o.ownerDocument;
-
- var sIndexQuery = "/inetsdk:topic/metadata/index";
- var oIndex = oDoc.selectSingleNode(sIndexQuery);
- var bNoDefIndex = false;
- if (oIndex)
- {
- if (oIndex.getAttribute("noindex"))
- {
- bNoDefIndex = true;
- }
-
- var oKeyWords = oIndex.selectNodes("kw");
- for (var iKW = 0; iKW < oKeyWords.length; iKW++)
- {
- aConcepts[oKeyWords[iKW].text.toLowerCase()] = "1";
- }
- }
-
- // delimeter specification indicates that the output is for IDX_CONCEPT
- // since indexer will index the topic name, don't repeat it in the concept list
- if (!bNoDefIndex && !sDelim)
- {
- var sNameQuery = "/inetsdk:topic/metadata/@name";
- var oName = oDoc.selectSingleNode(sNameQuery);
- if (oName)
- {
- aConcepts[oName.value] = "1";
- }
- }
-
- if (sDelim)
- {
- return StringFromHash(aConcepts, sDelim);
- }
- else
- {
- return aConcepts;
- }
- }
-
- // Collect keywords from the document and spit them out as <META KEYWORDS.../>
- // This code recognizes <kw> tags and <tla> and <term> tags with a kw attribute
- // Consider supporting <xref> with a kw attribute.
- // avoid dupes by converting all keywords to lowercase and by storing them in a hash table
- function GatherKeywords(o, sDelim)
- {
- var oDoc = o.ownerDocument;
-
- if (!sDelim)
- {
- sDelim = ",";
- }
-
- // don't pass a delimeter because we want to get back a hash table
- var aKeywords = GatherConcepts(o);
-
- var sQuery = "/inetsdk:topic/content//kw";
- var oNodes = oDoc.selectNodes(sQuery);
- var i;
- for (i = 0; i < oNodes.length; i++)
- {
- var oNode = oNodes[i];
- aKeywords[oNode.text.toLowerCase()] = "1";
- }
-
- sQuery = "/inetsdk:topic/content//tla[@kw]";
- oNodes = oDoc.selectNodes(sQuery);
- for (i = 0; i < oNodes.length; i++)
- {
- //at: Search the central pre-loaded acronyms.xml DOM.
- var sRid = oNodes[i].getAttribute("rid");
- var oAc = goLookup.RetrieveAcronym(sRid);
- if (oAc)
- {
- var oNode = oAc.selectSingleNode("primary");
- if (oNode)
- aKeywords[oNode.text.toLowerCase()] = "1";
- }
- }
-
- sQuery = "/inetsdk:topic/content//term[@kw]";
- oNodes = oDoc.selectNodes(sQuery);
- for (i = 0; i < oNodes.length; i++)
- {
- var oNode = oDoc.selectSingleNode("/inetsdk:topic/inetsdk:glossary/gloss_entry[@id = '" + oNodes[i].getAttribute("rid") + "']/@name");
- if (oNode)
- {
- aKeywords[oNode.text.toLowerCase()] = "1";
- }
- }
-
- return StringFromHash(aKeywords, sDelim);
- }
-
- var gSpecialContainer = {"seealso" : 1, "applies" : 1, "related_topics" : 1};
- function IsPrivilegedLink(o)
- {
- //return (gSpecialContainer[o.parentNode.nodeName] != null ? true : false);
-
- // need to walk the parent chain since links can be embedded inside if/sw and other markup
- // rather than directly inside a special container
- var oParent = o;
- while (oParent = oParent.parentNode)
- {
- if (gSpecialContainer[oParent.nodeName] != null)
- {
- return true;
- }
- }
- return false;
- }
-
- // determine whether or not this link should be enabled
- // rule: must be the first instance or must be explicitly enabled
- function ShouldLink(oSrc, oCtx)
- {
- return (oSrc.getAttribute("enabled") || IsPrivilegedLink(oSrc) || IsFirstLink(oSrc, oCtx) ? true : false);
- }
-
- // determine whether or not the node should be glossarized
- // rule: must be the first instance or must be explicitly enabled
-
- // keep tabs on glossary references. This is a more memory intensive but
- // less processing intensive (fewer DOM query/traverses), and more
- // reliable since a gloss entry may be referenced earlier in the tree but for a
- // different dev language
-
- function ShouldGlossarize(o)
- {
- var sID = o.getAttribute("rid");
- if (!sID) return false;
-
- if (typeof(ShouldGlossarize._table) == 'undefined')
- {
- ShouldGlossarize._table = new Array();
- ShouldGlossarize._table[sID] = 1;
- return true;
- }
-
- if (!ShouldGlossarize._table[sID])
- {
- ShouldGlossarize._table[sID] = 1;
- return true;
- }
-
- if (o.getAttribute("enabled"))
- {
- return true;
- }
-
- return false;
- }
-
-
- // determine if the link (o) is the first occurrence of a
- // cross-reference to the topic with the specified @rid
- // BUGBUG: Check for type="pn", and concatenate that onto the key
- function IsFirstLink(o, oCtx)
- {
- var sID = o.getAttribute("rid");
- if (!sID) return false;
-
- var sFid = o.getAttribute("fid"); // #fragment-id
- var sIid = o.getAttribute("iid"); // #interface-id
- var sCid = o.getAttribute("cid"); // #constant-id
-
- // use the devlang on the source tag before the global devlang
- var sDevLang = o.getAttribute("devlang");
- if (!sDevLang)
- {
- sDevLang = oCtx._devlang;
- }
-
- // differentiate between persistent and runtime requests
- var sType = o.getAttribute("type");
-
- var sKey = sID +
- (typeof(sDevLang) != 'undefined' ? sDevLang : '') +
- (sFid != null ? sFid : '') +
- (sIid != null ? sIid : '') +
- (sCid != null ? sCid : '') +
- (sType != null ? sType : '');
-
- if (typeof(IsFirstLink._linkTable) == 'undefined')
- {
- IsFirstLink._linkTable = new Array();
- IsFirstLink._linkTable[sKey] = 1;
- return true;
- }
-
- if (!IsFirstLink._linkTable[sKey])
- {
- IsFirstLink._linkTable[sKey] = 1;
- return true;
- }
-
- return false;
-
- }
-
- // In the current document, is this node the first of its type (term)
- // using this node's rid.
- // JK: This is the origianl IsFirst definition.
- // This is a temporary workaround until glossary becomes part of lookup.
- function IsFirstTerm(o)
- {
- var oTestNode;
- var sID = o.getAttribute("rid");
- if (!sID) return false;
- var oNestedVersions = o.ownerDocument.selectNodes("/inetsdk:topic/inetsdk:acronyms/acronym[./primary/tla/@rid = '" + sID + "']");
- var oThisNode;
- // find the first node in the document that uses this id.
- var oNode = o.ownerDocument.selectSingleNode("inetsdk:topic/content//" + o.nodeName + "[@rid='" + sID + "']");
-
- if (!oNode)
- {
- switch(o.parentNode.nodeName)
- {
- case "primary":
- {
- //need to check if there is another node that shares this tla...
- if(oNestedVersions.length>0)
- {
- oThisNode = o.ownerDocument.selectSingleNode("inetsdk:topic/content//" + o.nodeName + "[@rid='" + o.parentNode.parentNode.getAttribute("id") + "']");
- if(oThisNode)
- {
- for(i=0;i<oNestedVersions.length;i++)
- {
- oTestNode = o.ownerDocument.selectSingleNode("inetsdk:topic/content//" + o.nodeName + "[@rid='" + oNestedVersions[i].getAttribute("id") + "']");
- if (oTestNode)
- {
- if (uniqueID(oTestNode) < uniqueID(oThisNode))
- {
- return false;
- }
- }
- }
-
- return true;
- }
- else
- {
- return true;
- }
- }
- else
- {
- return true;
- }
-
- break;
-
- }
- case "secondary":
- {
- return false;
- break;
- }
- default:
- {
- }
-
- }
- return true;
- }
- else
- {
- switch(o.parentNode.nodeName)
- {
- case "secondary":
- {
- return false;
- break;
- }
- case "primary":
- {
- oThisNode = o.ownerDocument.selectSingleNode("inetsdk:topic/content//" + o.nodeName + "[@rid='" + o.parentNode.parentNode.getAttribute("id") + "']");
- if(oThisNode)
- {
- if (uniqueID(oNode) < uniqueID(oThisNode))
- {
- return false;
- }
-
- if (oNestedVersions.length>0)
- {
- for(i=0;i<oNestedVersions.length;i++)
- {
- oTestNode = o.ownerDocument.selectSingleNode("inetsdk:topic/content//" + o.nodeName + "[@rid='" + oNestedVersions[i].getAttribute("id") + "']");
- if (oTestNode)
- {
- if (uniqueID(oTestNode) < uniqueID(oThisNode))
- {
- return false;
- }
- }
- }
-
- return true;
- }
- else
- {
- return true;
- }
- }
- else
- {
- return true;
- }
- }
- default:
- {
- //this should be the case where there it isn't a nested tla...
- break;
- }
- }
- }
-
- if (uniqueID(oNode) == uniqueID(o))
- {
- if (oNestedVersions.length>0)
- {
- for(i=0;i<oNestedVersions.length;i++)
- {
- oTestNode = o.ownerDocument.selectSingleNode("inetsdk:topic/content//" + o.nodeName + "[@rid='" + oNestedVersions[i].getAttribute("id") + "']");
- if (oTestNode)
- {
- if (uniqueID(oTestNode) < uniqueID(oNode))
- {
- return false;
- }
- }
- }
-
- return true;
- }
- else
- {
- return true;
- }
- }
- else
- {
- if(o.parentNode.nodeName=="primary")
- {
- return true;
- }
- else
- {
- return false;
- }
- }
- }
-
-
- // Change the file extension of the path. If the extension is empty,
- // do nothing
- function ChangeExt(sPath, sExt)
- {
- if (!sExt || /^$/.test(sExt))
- {
- return sPath;
- }
-
- if (!/^\./.test(sExt))
- {
- sExt = "." + sExt;
- }
-
- return sPath.substring(0, sPath.lastIndexOf(".")) + sExt;
- }
-
- // Given d:\foo\bar\goo.htm, return "htm"
- function JustExt(sPath)
- {
- var iPos = sPath.lastIndexOf(".");
- if (iPos >= 0 && sPath.length > iPos+1)
- {
- return sPath.substring(iPos+1);
- }
- else
- {
- return "";
- }
- }
-
- // Given d:\foo\bar\goo.htm, return "goo.htm"
- function JustFName(sPath)
- {
- sPath = sPath.replace(/[\\\\]/g, "/"); // convert backslashes to forward slashes
- var aParts = sPath.split("/"); // split on forward slash
- return aParts[aParts.length-1];
- }
-
- // Given d:\foo\bar\goo.htm, return "d:\foo\bar"; slashes a reversed
- function JustPath(sPath)
- {
- sPath = sPath.replace(/[\\\\]/g, "/"); // convert backslashes to forward slashes
- var aParts = sPath.split("/"); // split on forward slash
- aParts.length -= 1;
- return (aParts.length == 0 ? "." : aParts.join("/"));
- }
-
- // Given d:\foo\bar\goo.htm, return "goo"
- function JustStem(sPath)
- {
- var sFile = JustFName(sPath);
- var aParts = sFile.split(".");
- aParts.length -= 1;
- return aParts.join(".");
- }
-
-
- // dependency: observe the explicit XQL query
- function GetPublishedPathOfTopic()
- {
- if (typeof(GetPublishedPathOfTopic.pubpath) == 'string')
- {
- return GetPublishedPathOfTopic.pubpath;
- }
-
- var oPubPath = ownerDocument.selectSingleNode("/HTML/HEAD/ph:header/ph:data/XML[@ID='_topicdata']/@pubpath");
- if (oPubPath)
- {
- return (GetPublishedPathOfTopic.pubpath = oPubPath.value);
- }
- else
- {
- return null;
- }
- }
-
- // wraps the GeneratePath call because returning null to an xsl:eval is fatal
- function GeneratePathWrapper(sPubPath, sDestPath, sMedia)
- {
- var sFinalPath = GeneratePath(sPubPath, sDestPath, sMedia);
- if (typeof(sFinalPath) == 'string')
- {
- return sFinalPath;
- }
- else
- {
- return "";
- }
- }
-
- // Build a path relative to the published location of the current
- // topic if the media is 'chm' or 'HXS'.
- // Otherwise return the path unchanged.
- function GeneratePath(sPubPath, sDestPath, sMedia)
- {
- if (typeof(sMedia) != 'string' || (sMedia != 'chm' && sMedia != 'hxs'))
- {
- return sDestPath;
- }
-
- if (!sPubPath)
- {
- // BUGBUG: Cache the error somewhere
- //oDest.error = "published path unavailable";
- return null;
- }
-
- var sHREF;
- // BUGBUG: htm extension is hard-coded in the CHM case.
- sHREF = MakeRelative(sPubPath, sDestPath);
- if (!sHREF)
- {
- // BUGBUG: Cache the error somewhere
- //oDest.error = "VROOT2Relative failure.";
- return null;
- }
- else
- {
- // extension map. Only change the target path if its extension is in the map.
- // BUGBUG: Hardcoded...
- var aExt = {'asp' : 'htm'};
- var sExt = JustExt(sHREF);
- if (sExt)
- {
- var sNewExt = aExt[sExt];
- if (sNewExt)
- {
- sHREF = ChangeExt(sHREF, sNewExt);
- }
- }
- return sHREF;
- }
-
- }
-
- // Compose a path to the specified destination path relative to the specified container path
- // The composition is performed case insensitively
- function MakeRelative(sContainer, sDestPath)
- {
- // c:/sitebuilder/workshop/author/dhtml/reference/properties.htm
- // /sitebuilder/shared/css/ie4-wks.css
- // ../../../../shared/css/ie4-wks.css
-
- // c:/sitebuilder/workshop/author/dhtml/reference/properties.htm
- // /workshop/author/dhtml/reference/properties/accessKey.htm
- // properties/accessKey.htm
-
- // c:/sitebuilder/workshop/author/dhtml/reference/properties.htm
- // /workshop/code/common.js
- // ../../../code/common.js
-
- // path is already relative
- if (/^\.\./.test(sDestPath))
- {
- return sDestPath;
- }
-
- // normalize the paths
- var oRegBS = /\\/g;
- sContainer = sContainer.replace(oRegBS, "/");
- sDestPath = sDestPath.replace(oRegBS, "/");
-
- if (/^http:\/\//.test(sDestPath))
- {
- return sDestPath;
- }
-
- // BUGBUG: make sure topics are on the same drive/protocol/server
- var oRegNoProtocol = /^(file:\/\/\/)?([a-zA-z]):/;
- sContainer = sContainer.replace(oRegNoProtocol, "");
- sDestPath = sDestPath.replace(oRegNoProtocol, "");
-
- sDestPath = sDestPath.replace(/^\//, ""); // lop leading slash to eliminate empty first array element after split
-
- var aSrc = sContainer.split(/\//);
- aSrc.length -= 1; // lop off the filename from the container (assume container is a reference to a file)
-
- var bTrailingSlash = (/\/$/.test(sDestPath)); // preserve trailing slash
- var aDest = sDestPath.split(/\//);
-
- var iSrcLen = aSrc.length, iDestLen = aDest.length;
- var iSrcIndex = 0, iDestIndex = 0, iNoMatch = 0;
-
- // walk forward looking for matching portion of path
- var bMatched = 0;
- for (iSrcIndex = 0; iSrcIndex < iSrcLen; iSrcIndex++)
- {
- if (aSrc[iSrcIndex].toLowerCase() != aDest[iDestIndex].toLowerCase())
- {
- iNoMatch++;
- }
- else
- {
- bMatched = 1;
- break;
- }
- }
-
- if (bMatched)
- {
-
- var aRelPath = new Array();
-
- while (iSrcIndex < iSrcLen && iDestIndex < iDestLen && aSrc[iSrcIndex].toLowerCase() == aDest[iDestIndex].toLowerCase())
- {
- iSrcIndex++; iDestIndex++;
- }
-
- // tack remaining portion of destination path onto the end of the result
- while (iDestIndex < iDestLen)
- {
- aRelPath[aRelPath.length] = aDest[iDestIndex];
- iDestIndex++;
- }
-
- var sRelPath = aRelPath.join('/');
-
- // climb out of what remains of the source (excluding the filename)
- while (iSrcIndex < iSrcLen)
- {
- sRelPath = "../" + sRelPath;
- iSrcIndex++;
- }
-
- return sRelPath + (bTrailingSlash ? "/" : "");
- }
- else // BUGBUG: no overlap, so just return what was passed in?
- {
- return sDestPath;
- }
- }
-
- // return the string s with the first letter capitalized
- function Proper(s)
- {
- return (/^(.)(.*)/.test(s) ? RegExp.$1.toUpperCase() + RegExp.$2 : s);
- }
-
- // return the proper string associated with the supplied page type
- function ProperPageType(s)
- {
- switch ( s )
- {
- case "attribute":
- case "behavior":
- case "collection":
- case "constants":
- case "event":
- case "function":
- case "method":
- case "object":
- case "property":
- case "rule":
- return Proper( s );
- case "dhcmdid":
- return "Command Identifier";
- case "dhfilter":
- return "Filter";
- case "dhfilter_method":
- return "Method";
- case "dhfilter_property":
- return "Property";
- case "enum":
- return "Enumerated Type";
- case "howto":
- return "Tutorial";
- case "iface":
- return "Interface";
- case "ovw":
- return "Overview";
- case "pseudo_element":
- return "Pseudo-element";
- case "struct":
- return "Structure";
- default:
- return "";
- }
- }
-
- // chains 5-04-01
- // Used by glossary_page.xsl and alphabetic_link.xsl
- // Checks a gloss_entry node or nodeSet to see if any nodes contain all the filters defined for a page
- function CheckFilters(aGlossaryNodeOrNodes, bIsNodeSet)
- {
- var aPageTechs = this.selectNodes("//inetsdk:topic/metadata/tech");
- var aTechStrings = new Array();
- for (i = 0; i < aPageTechs.length; i++)
- {
- aTechStrings[i] = aPageTechs[i].getAttribute("value");
- }
-
- if (bIsNodeSet == false)
- {
- // aGlossaryNodeOrNodes is a single node
- aNodeTechs = aGlossaryNodeOrNodes.selectNodes("tech");
- if (aNodeTechs.length == 0) return true; // default is to include
- iNumberFound = 0;
-
- for (j = 0; j < aNodeTechs.length; j++)
- {
- for (k = 0; k < aTechStrings.length; k++)
- {
- if (aTechStrings[k] == aNodeTechs[j].getAttribute("value"))
- iNumberFound++
- }
- }
-
- if (iNumberFound == aTechStrings.length) return true;
- }
- else
- {
- // for each node, check to see if all page techs are present
- // if so, set bFound to true
- for (i = 0; i < aGlossaryNodeOrNodes.length; i++)
- {
- oNode = aGlossaryNodeOrNodes[i];
- aNodeTechs = oNode.selectNodes("tech");
- if (aNodeTechs.length == 0) return true; // default is to include
- iNumberFound = 0;
-
- for (j = 0; j < aNodeTechs.length; j++)
- {
- for (k = 0; k < aTechStrings.length; k++)
- {
- if (aTechStrings[k] == aNodeTechs[j].getAttribute("value"))
- iNumberFound++
- }
- }
-
- if (iNumberFound == aTechStrings.length) return true;
- }
- }
-
- return false;
- }
-
- // chains 6-8-01
- // Used by utopia-wks.xsl
- // Creates string for @content in META @description
- // Converts quotes and apostrophies to entities
- // Removes line breaks and tabs.
- // This function is necessary for Utopia because the META description
- // becomes a jscript object property in the utopia-wks.xsl transform
- // BUGBUG: currently loses text for xref and tla nodes in oNode
- // It should apply a stylesheet to oNode that converts these nodes to text
- function FormatNodeForMETA(oNode, sXSL)
- {
- var sText = "";
- if (!oNode) return sText;
- sText = oNode.text;
-
- var i = 0;
- while ((i = sText.indexOf("\"")) != -1)
- {
- sText = sText.substring(0, i) + """ + sText.substring(i + 1);
- }
-
- //var i = 0;
- while ((i = sText.indexOf("\'")) != -1)
- {
- sText = sText.substring(0, i) + "'" + sText.substring(i + 1);
- }
-
- //var i = 0;
- while ((i = sText.indexOf("\n")) != -1)
- {
- sText = sText.substring(0, i) + sText.substring(i + 1);
- }
-
- //var i = 0;
- while ((i = sText.indexOf("\r")) != -1)
- {
- sText = sText.substring(0, i) + sText.substring(i + 1);
- }
-
- //var i = 0;
- while ((i = sText.indexOf("\t")) != -1)
- {
- sText = sText.substring(0, i) + sText.substring(i + 1);
- }
-
- return sText;
- }
-
- // chains 6-19-01
- // Used by scr_property.xsl
- // Helps page determine whether property belongs to an HTML element
- // and should use a syntax section that includes HTML syntax
- function DoesObjectHavePN()
- {
- var oObjectNodes;
- var oTNode;
- var sRid = "";
- var sPN = "";
-
- oObjectNodes = this.selectNodes("//metadata/applies/object");
-
- for (i = 0; i < oObjectNodes.length; i++)
- {
- sRid = oObjectNodes(i).getAttribute("rid");
- oTNode = goLookup.RetrieveTarget(sRid);
- if (!oTNode) continue;
- else sPN = oTNode.getAttribute("pn")
- if (sPN && sPN != "") return true;
- }
-
- return false;
- }
-
- // chains 6-20-01
- // Used by scr_property.xsl
- // Helps page determine whether property belongs to an HTML element
- // and should use a syntax section that includes HTML syntax
- function ObjectTypeEquals(sType)
- {
- var oObjectNodes;
- var oTNode;
- var sRid = "";
- var sObjectType = "";
-
- oObjectNodes = this.selectNodes("//metadata/applies/object");
-
- for (i = 0; i < oObjectNodes.length; i++)
- {
- sRid = oObjectNodes(i).getAttribute("rid");
- oTNode = goLookup.RetrieveTarget(sRid);
- if (!oTNode) continue;
- else sObjectType = oTNode.getAttribute("type")
- if (sObjectType && sObjectType == sType) return true;
- }
-
- return false;
- }
-
- // chains 6-26-01: Used by utopia-wks.xsl
- // Script inserted into Utopia template via sHeaderString must have additional back slashes in
- // line breaks and quotes for proper escape character sequence
- function FormatForUtopiaHeaderString(oNode, sProjRoot)
- {
- var sText = "";
- if (!oNode) return sText;
-
- var sTestString = "/production/xml/";
- var sReplacementText = sProjRoot + "/";
- var oRegExp = new RegExp(sTestString, "g");
-
- sText = oNode.xml;
-
- if (sText.indexOf(sTestString) != -1)
- sText = sText.replace(oRegExp, sReplacementText);
-
- var i = 0;
- while ((i = sText.indexOf("\n", i)) != -1)
- {
- sText = sText.substring(0, i - 1) + "\\n" + sText.substring(i + 1);
- }
-
- var i = 0;
- while ((i = sText.indexOf("\"", i + 2)) != -1)
- {
- sText = sText.substring(0, i) + "\\\"" + sText.substring(i + 1);
- }
-
- return sText;
- }
-
- // chains 6-26-01
- // Used by utopia-wks.xsl
- // Gets the name of a file from an @HREF attribute that specifies a path to a script or css file
- function GetFileName(oNode)
- {
- var sFileName = "";
- if (!oNode) return sFileName;
-
- sFullName = oNode.nodeValue;
- if (sFullName == "") return sFileName;
-
- var iLastSlash = sFullName.lastIndexOf("/");
- if (iLastSlash == -1) iLastSlash = sFullName.lastIndexOf("\\");
- if (iLastSlash == -1) return sFileName;
- else return sFullName.substring(iLastSlash + 1);
- }
-
- function BuildObjectList()
- {
- //debugger;
- var sRet = "";
- var oXMLDoc = this.ownerDocument;
- var sName = oXMLDoc.selectSingleNode("//metadata/@name").value;
- var sCriteria = "[dlang/@value='" + goLookup._oCtx._devlang + "']";
- //if (!NeedsDisambiguation(sName, goDest, sCriteria))
- // return sRet;
- // Check with lookupbyName type thing for multiple pages with same metadata/@name
-
- // construct string from applies/object (or applies/iface too?)
- var oAppliesNode = oXMLDoc.selectSingleNode("//applies");
- if (!oAppliesNode) return sRet;
- var oObjectNodes = oAppliesNode.selectNodes("object");
- sRet = " (";
- for (i = 0; (i < 3) && i < (oObjectNodes.length); i++)
- {
- sObjectRid = oObjectNodes[i].getAttribute("rid");
- // lookup in targets and get name
- goLookup.LookupByRID(sObjectRid, goDest);
- sObjectName = goDest.GetPersistentName();
- if (sObjectName == "" || sObjectName == undefined) sObjectName = goDest.GetCaption();
- //if (sObjectName == "") sObjectName = oObjTarg.GetAttribute("name");
-
- sRet = sRet + sObjectName;
- if (i + 1 < oObjectNodes.length && i < 2) sRet = sRet + ", ";
- }
- if (oObjectNodes.length > 3) sRet = sRet + ", ...";
- sRet = sRet + ")";
- return sRet;
- }
-
- /*
- function NeedsDisambiguation(sName, oDest, sCriteria)
- {
- var bRet = false;
-
-
- var bOk = false;
- var sTargXML = null;
- var sTPath = goLookup._oCtx._sDrive + goLookup._oCtx.GetPathOf("targets");
- var oTNodes = null;
- var oTNode = null;
- var oData = null;
- var bLuCache = goLookup._oCtx.CacheLookups();
-
- oData = goLookup.EnsureData(bLuCache);
- bLuCache = goLookup._oCtx.CacheLookups();
-
- oDest.Init();
-
- if (sName)
- {
- oDest.SetCaption(sName);
-
- sCriteria = NormalizeCriteria(sCriteria);
-
- if (bLuCache && oData)
- {
- // Try to use the LuCache Lookup Cache.
- try
- {
- // Call LuCache to lookup the name and get back the node-xml.
- sTargXML = oData.LookupField(sName, "name", sTPath, sCriteria);
- }
- catch(e)
- {
- sTargXML = null;
- }
- if (sTargXML)
- {
- var oTDom = goLookup._oCtx._oTDom;
-
- // Now use mini-dom node to load node-xml and get a node.
- oTDom.async = false;
- oTDom.loadXML(sTargXML);
- oTNode = oTDom.documentElement;
- if (oTNode)
- bOk = true;
- else
- goLookup._error = "cannot load node xml.";
- }
- else
- goLookup._error = "cannot locate " + sName;
- }
- else
- {
- // Try to use a loaded DOM for lookups.
- if (bLuCache && !oData)
- oData = goLookup.EnsureData(false);
- if (oData)
- {
- oTNodes = oData.selectNodes("/inetsdk:targets/targ[@name='" + sName + "']" + sCriteria);
- //oTNodes = oTNodes.selectNodes("dlang[@value='" + sCriteria + "']");
- if (oTNodes.length > 1) bRet = true;
- }
- else
- goLookup._error = "cannot create access to targets.";
- }
- }
-
- return bRet;
- }
- */
-
- function NeedsNewGif()
- {
- //return true;
- sXml = this.xml;
- if (sXml.indexOf("new.gif") != -1) return true;
- else return false;
- }
-
- /********************
- * unused code below *
- *********************/
-
- // force see also links to be enabled
- //BUGBUG: Can't modify a read-only node.
- //BUGBUG: By design the XML document is read-only during transformation.
- /*
- function TweakXrefs(o)
- {
- var aPaths = new Array("inetsdk:topic/content/seealso/xref");
- for (var i = 0; i < aPaths.length; i++)
- {
- var oSeeNodes = o.selectNodes(aPaths[i]);
- for (var i = 0; i < oSeeNodes.length; i++)
- {
- var oNode = oSeeNodes(i);
- oNode.setAttribute("enabled", "1");
- }
- }
- }
-
- function IsHex(s)
- {
- return s.match(/^0x/i) ? true : false;
- }
-
- // convert s to hexidecimal
- function toHex(s)
- {
- var sHexDigits = "0123456789ABCDEF", sResult = "";
-
- s = parseInt(s);
-
- while (s > 15)
- {
- i = s % 16;
- sResult = sHexDigits.charAt(i) + sResult;
- s = Math.floor(s/16);
- }
- sResult = sHexDigits.charAt(s) + sResult;
- return sResult;
- }
-
-
- // VB outputs values in decimal format.
- // In the lower pane of the object browser it outputs values >= 16 in decimal followed by (&Hxx)
- function VBOutput(s)
- {
- var iResult = parseInt(s);
- var sResult = "";
- sResult += iResult;
-
- // append the hex value if s is big enough
- if (iResult >= 16)
- {
- sResult += " '";
- if (IsHex(s))
- {
- sResult += s.replace(/^0x/i, '&H');
- }
- else
- {
- sResult += "&H" + toHex(iResult);
- }
- }
-
- return sResult;
- }
-
- Not currently in use
- // Strip the protocol from the beginning of the specified path.
- function StripProtocol(s)
- {
- return s.replace(/^((file|http):)?\/+([a-z]:)?/i, "")
- }
-
- // formerly used to handle building the VARIANT subtype string when resolving a dtype
- // Now we use pure script instead
- function IsSecond2Last(o)
- {
- var iSiblings = o.parentNode.childNodes.length;
- return (childNumber(o) == iSiblings-1) ? true : false;
- }
-
- */
- ]]>
-